package shared;

import java.io.Serializable;
import java.nio.file.Path;
import java.util.ArrayList;

import client.Configuration;
import shared.*;

public class FileDescriptor implements Serializable
{


    private static final long serialVersionUID = 2222L;

    private long fileID = -1;

    private String pathname;

    private ArrayList<DataServerState> dataServers;

    private ArrayList<String> owners;

    private String hash;

    private boolean isDirectory = false;

    private boolean isDeleted = false;

    private boolean isDeletedLocal = false;

    private boolean isModifiedLocal = true;

    private long version = 0;

    private boolean isLocked = false;

    private long timeOfLock;

    public FileDescriptor()
    {
	super();
	this.owners = new ArrayList<String>();
    }

    // dataservers and owners will get a copy of the arraylist
    @SuppressWarnings("unchecked")
    public FileDescriptor(FileDescriptor descriptor)
    {
	super();
	this.fileID = descriptor.fileID;
	this.pathname = descriptor.pathname;
	this.dataServers = (ArrayList<DataServerState>) descriptor.dataServers
		.clone();
	this.owners = (ArrayList<String>) descriptor.owners.clone();
	this.hash = descriptor.hash;
	this.isDirectory = descriptor.isDirectory;
	this.isDeleted = descriptor.isDeleted;
	this.isDeletedLocal = descriptor.isDeletedLocal;
	this.isModifiedLocal = descriptor.isModifiedLocal;
	this.version = descriptor.version;
	this.isLocked = descriptor.isLocked;
	this.timeOfLock = descriptor.timeOfLock;
    }

    public String toString()
    {
	String s = "";
	s += "FileID:" + this.fileID + ", FileName:" + this.pathname;
	return s;
    }

    public long getFileID()
    {
	return fileID;
    }

    public void setFileID(long fileID)
    {
	this.fileID = fileID;
    }

    public String getPathname()
    {
	return pathname;
    }

    public void setPathname(String pathname)
    {
	this.pathname = pathname;
    }

    public ArrayList<DataServerState> getDataServers()
    {
	return dataServers;
    }

    public void setDataServers(ArrayList<DataServerState> dataServers)
    {
	this.dataServers = dataServers;
    }

    public ArrayList<String> getOwners()
    {
	return owners;
    }

    public void setOwners(ArrayList<String> owners)
    {
	this.owners = owners;
    }

    public String getHash()
    {
	return hash;
    }

    public void setHash(String hash)
    {
	this.hash = hash;
    }

    public boolean isDeleted()
    {
	return isDeleted;
    }

    public void setDeleted(boolean isDeleted)
    {
	this.isDeleted = isDeleted;
    }

    public long getVersion()
    {
	return version;
    }
    
    @Deprecated
    public Path getAbsolutePath(Path homePath){
    	Path absolutePath = homePath.resolve(this.pathname);
    	return absolutePath;
    }

    public void setVersion(long version)
    {
	this.version = version;
    }

    public boolean isDirectory()
    {
	return isDirectory;
    }

    public void setDirectory(boolean isDirectory)
    {
	this.isDirectory = isDirectory;
    }

    public boolean isDeletedLocal()
    {
	return isDeletedLocal;
    }

    public void setDeletedLocal(boolean isDeletedLocal)
    {
	this.isDeletedLocal = isDeletedLocal;
    }

    public boolean isModifiedLocal()
    {
	return isModifiedLocal;
    }

    public void setModifiedLocal(boolean isModifiedLocal)
    {
	this.isModifiedLocal = isModifiedLocal;
    }

    public boolean isLocked()
    {
	if (isLocked == false)
	    return isLocked;
	else
	{
	    java.util.Calendar calendar = new java.util.GregorianCalendar();
	    if (calendar.getTimeInMillis() - this.timeOfLock > Constants.LOCK_EXPIRY_LENGTH)
	    {
		this.isLocked = false;
		return isLocked;
	    } else if (calendar.getTimeInMillis() < this.timeOfLock)
	    {
		this.timeOfLock = calendar.getTimeInMillis();
		return this.isLocked;
	    } else
		return this.isLocked;
	}
    }

    public void setLocked(boolean isLocked)
    {
	if (isLocked == false)
	    this.isLocked = isLocked;
	else
	{
	    java.util.Calendar calendar = new java.util.GregorianCalendar();
	    this.timeOfLock = calendar.getTimeInMillis();
	    this.isLocked = true;
	}
    }

}
